#include "GenericDBFile.h"

bool isDirty = false;
HeapDBFile::HeapDBFile(){
    curPageInFile = 0;
}


int HeapDBFile::Create(char* f_path){

        return GenericDBFile::Create(f_path);
}

int HeapDBFile::Open(char * f_path){

        return GenericDBFile::Open(f_path);
}

void HeapDBFile::Load(Schema &f_schema, char *loadpath) {
    // success in open file?
    // deal with multiple call for this function?
    // for now, suppose this function is used to initialize and use only once

    FILE* inputFile = fopen(loadpath,"r");
    Record temp;
    // whichPage is not neccesary
    off_t whichPage = 0;
    while(temp.SuckNextRecord(&f_schema, inputFile) == 1){
        if(dbPage.Append(&temp) == 0) {
            dbFile.AddPage(&dbPage, whichPage++);
            dbPage.EmptyItOut();
            dbPage.Append(&temp);
        }
    }
    dbFile.AddPage(&dbPage, whichPage);
    dbPage.EmptyItOut();
    MoveFirst();
}

void HeapDBFile :: MoveFirst () {
    if(dbFile.GetFilDes() < 0)
        return;
    curPageInFile = 0;
}

int HeapDBFile :: Close () {
    if(dbFile.Close() == 0)
        return 0;
    else
        return 1;
}

void HeapDBFile :: Add (Record &addme) {
    // for now, no check on whether still can insert into bin file or not
    if(isDirty) {
        if(dbPage.Append(&addme) == 0) {
            if(dbFile.GetLength() == 0)
                dbFile.AddPage(&dbPage, dbFile.GetLength());
            else
                dbFile.AddPage(&dbPage, dbFile.GetLength()-1);
            dbPage.EmptyItOut();
            dbPage.Append(&addme);
        }
    }
    else {
        dbPage.EmptyItOut();
        dbPage.Append(&addme);
        isDirty = true;
    }
}

void HeapDBFile :: AdditionAddPage(){
    if(dbFile.GetLength() == 0)
        dbFile.AddPage(&dbPage, dbFile.GetLength());
    else
        dbFile.AddPage(&dbPage, dbFile.GetLength()-1);
    dbPage.EmptyItOut();
}

int HeapDBFile::GetNext (Record &fetchme) {
    if(!isDirty) {
        if(dbPage.GetFirst(&curRecord) == 1) {
            fetchme.Consume(&curRecord);
            return 1;
        }
        else {
            if(curPageInFile >= dbFile.GetLength() - 1) {
                return 0;
            }
            else {
                dbPage.EmptyItOut();
                dbFile.GetPage(&dbPage, curPageInFile++);
                dbPage.GetFirst(&curRecord);
                fetchme.Consume(&curRecord);
                return 1;
            }
        }
    }
    else {
        if(dbFile.GetLength() == 0)
            dbFile.AddPage(&dbPage, dbFile.GetLength());
        else
            dbFile.AddPage(&dbPage, dbFile.GetLength() - 1);
        dbPage.EmptyItOut();
        dbFile.GetPage(&dbPage, curPageInFile++);
        dbPage.GetFirst(&curRecord);
        fetchme.Consume(&curRecord);
        isDirty = false;
        return 1;
    }
}

int HeapDBFile :: GetNext (Record &fetchme, CNF &cnf, Record &literal) {
    ComparisonEngine comp;
    Record temp;
    while(GetNext(temp) == 1) {
        if(comp.Compare(&temp, &literal, &cnf)) {
            fetchme.Consume(&temp);
            return 1;
        }
    }
    return 0;
}

HeapDBFile::~HeapDBFile(){
}
